<?php
namespace hclient\formatters;

use hclient\base\File;
use hclient\base\Request;

/**
 * socket http 请求格式化
 *<B>说明：</B>
 *<pre>
 * 略
 *</pre>
 */
class HttpFormatter implements FormatterInterface
{
    public function format(Request $request):void
    {
        $request->setContent($this->getHttp($request));
    }

    protected function getHttp(Request $request):string
    {
        $requestData =  $this->getBody($request);

        // header lines
        $requestHeaders = $request->getRequestHeader();
        $pathInfo = parse_url($request->getUrl());
        $method = strtoupper($request->getMethod());
        $port = !empty($pathInfo['port'])  ? ':' . $pathInfo['port'] : '';

        array_unshift($requestHeaders,$method  . ' ' . $pathInfo['path'] . ' HTTP/1.0');
        array_push($requestHeaders,'Host: '.$pathInfo['host'] . $port);
        array_push($requestHeaders,'Content-Connection: close');
        array_push($requestHeaders,'Content-Length: '.strlen($requestData));
        array_push($requestHeaders,'Accept: */*');

        return implode("\r\n",$requestHeaders) . str_repeat("\r\n",2) . $requestData;
    }

    protected function getBody(Request $request)
    {

        if (!empty($request->getRequestData())) {
            return  $this->getHtmlContent($request);
        } else {
            return '';
        }
    }


    protected function getHtmlContent(Request $request):string
    {

        $headers = $request->getHeaders();
        $contentType = $headers->get('Content-Type');

        // 构建 multipart 边界（必须是唯一字符串）
        $boundary = '--' . bin2hex(random_bytes(8));
        // 手动构建 multipart 内容体
        $content = '';
        foreach ($request->getRequestData() as $name => $value) {
            // 文本字段处理
            if ($value instanceof File || $value instanceof \CURLFile) {
                $file = $value->name;
                // 获取文件内容和 MIME 类型
                $mimeType = $value->getMimeType() ? : 'application/octet-stream';
                $content .= '--' . $boundary . "\r\n" .
                    'Content-Disposition: form-data; name="' . $name . '"; filename="' . $value->getFilename() . '"'. "\r\n" .
                    'Content-Type:'. $mimeType . "\r\n\r\n" .
                    file_get_contents($file) . "\r\n";
            } else {
                $content .= '--' . $boundary ."\r\n" .
                    'Content-Disposition: form-data; name="' . $name . '"' . "\r\n\r\n" .
                    $value . "\r\n";
            }
        }
        $content .= '--' . $boundary ."--\r\n";
        $headers->set('Content-Type', 'multipart/form-data;boundary=' . $boundary);

        return $content;
    }
}
